#include "sort.h"

/** @fn     sortBubble(item *wRoot, int dir)
    @brief  sorts a list using the bubblesort algorithm
    @param  wRoot   the pointer to the list
    @param  dir     the direction of the sort action (1 = descending, 2 = ascending);
    @return 1 on succesful sort, NULL on fail
    */
/******************  pseudocode  ******************
procedure bubbleSort( A : list of sortable items ) defined as:
  do
    swapped := false
    for each i in 0 to length(A) - 2 inclusive do:
      if A[i] > A[i+1] then
        swap( A[i], A[i+1] )
        swapped := true
      end if
    end for
  while swapped
end procedure
*/
int sortBubble(item *wRoot, int dir){
    //exit function upon invalid parameter
    if(!wRoot){return((int) NULL);}
    item *ptr = wRoot;

    if(DEBUG){cout << "\nsorting list @ " << hex<<wRoot << endl;}
    //implementation of bubblesort algorithm

    //bool to check wether swapped has been executed
    int swapped = 0;

    do{
        //clear bool for each iteration
        ptr = wRoot;
        swapped = 0;

        //step through list
        while(ptr->next != (item*) NULL){
            //if not in order, swap elements
            if(((ptr->content) == (char*) NULL) || ((ptr->next->content) == (char *) NULL)){
                throw "empty char pointers";
            }

            if(wordCompare((ptr->content), (ptr->next->content)) == 1){ //i subbed for dir
                if(DEBUG>4){
                    //printf("\nswapping 0x%X \"%s\" to 0x%X \"%s\"", (int) ptr->content, ptr->content, (int) ptr->next->content, ptr->next->content);
                    //cout << "swapping " << ptr->content
                }
                itemSwap(ptr, ptr->next);
                swapped++;
            }
            ptr = ptr->next;
        }
        ptr = wRoot;
    }while(swapped);

    if(DEBUG){cout << "sort succeeded" << endl;}

    return(1);
}

/** @fn     filterClones(item *wRoot)
    @brief  removes all the clones (double entries) from a list
    @param  wRoot   the pointer to the list
    @return the amount of successful purges, NULL on fail
    */
struct item* detectClones(item *wRoot){
    item *ptr = wRoot;
    //int setchanged = 0;

    //item pointer is not empty
    while(ptr){
        //next item pointer is set
        if(ptr->next){
            //check if current word is equal to next word
            while(wordCompare(ptr->content, ptr->next->content) == 0){
                //increase count if equal
                ptr->count++;
                //return the pointer to the clone
                return(ptr->next);
            }
            ptr = ptr->next; //goto next item
        }else{
            return((item*) NULL);
        }
    }
    return((item*) NULL);
}

int itemSwap(item *wA, item *wB){

    if(wA == NULL || wB == NULL){return((int) NULL);}

    int pWordA = (int) wA->content;
    int lenA = wA->len;
    int countA = wA->count;

    int pWordB = (int) wB->content;
    int lenB = wB->len;
    int countB = wB->count;

    wA->content = (char *) pWordB;
    wB->content = (char *) pWordA;
    wA->len = lenB;
    wB->len = lenA;
    wA->count = countB;
    wB->count = countA;

    return(1);
}

/** @fn     int itemRemove(item *wA)
    @brief  removes an item from  the linked list
    @param  wItem   pointer of the item to remove
    @return returns 1 on succes, 0 on fail;
    */
int itemRemove(item *wItem){
    if(!wItem){return((int) NULL);}

    int next = (int) wItem->next;
    int prev = (int) wItem->prev;

    if(next){wItem->prev->next = (item*) next;}
    if(prev){wItem->next->prev = (item*) prev;}

    delete wItem->content;
    delete wItem;
    return(1);
}
